package com.aier.entrance.service.impl;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import net.eicp.ghostboy.futil.MD5Util;
import net.eicp.ghostboy.futil.RandomUtil;

import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Component;

import com.aier.admin.service.IAdminEntranceService;
import com.aier.common.common.Constant;
import com.aier.common.common.SystemConfigStatic;
import com.aier.common.dao.ICommonDAO;
import com.aier.entrance.common.EntranceICFinalData;
import com.aier.entrance.common.EntranceServerData;
import com.aier.entrance.entity.EntranceDevice;
import com.aier.entrance.entity.EntranceDeviceRowMapper;
import com.aier.entrance.service.IEntranceCardService;
import com.aier.entrance.service.IEntranceInitCommonService;
import com.aier.school.entity.SchoolGradeAttendance;
import com.aier.school.entity.SchoolTeacherIcard;
import com.aier.school.entity.TeacherIcardInfo;
import com.aier.school.entity.UserIcardInfo;
import com.aier.school.entity.mapper.SchoolGradeAttendanceRowMapper;
import com.aier.school.entity.mapper.SchoolTeacherIcardRowMapper;
import com.aier.school.entity.mapper.TeacherIcardInfoRowMapper;
import com.aier.school.entity.mapper.UserIcardInfoRowMapper;

@Component("entranceCardService")
public class EntranceCardServiceImpl_J implements IEntranceCardService {

    @Resource(name = "commonDao")
    private ICommonDAO commonDao;
    @Resource(name="entranceInitCommonService")
    private IEntranceInitCommonService entranceInitCommonService;
    
    public void setCommonDao(ICommonDAO commonDao) {
        this.commonDao = commonDao;
    }

    @Override
    public int userBindIC(long uid, String ichead, String icbody, String icfoot) {
        return -1;
    }

    @Override
    public long[] updateSwingICCard(String sn, String icisn, short operate,String recordTime) {
    	System.out.println("sn is "+sn);
        if(null==sn){
            return new long[] { EntranceICFinalData.SWINGICCARD_STATE_NOTHING };//无该设备
        }
        EntranceDevice ed = EntranceServerData.mapED.get(sn);
        System.out.println("ed is "+ed);
        if (null == ed) {
            return new long[] { EntranceICFinalData.SWINGICCARD_STATE_NOTHING };//无该设备
        }
        if (ed.getState() != EntranceICFinalData.ENTRANCE_STATE_ON) {
            return new long[] { EntranceICFinalData.SWINGICCARD_STATE_STOP };//门禁设备停用
        }
        
        
        try {
            //学校卡id
            Long scard_id = (Long) commonDao.listByObject("select si.icid from school_icard si where si.sid=? and si.state=? " +
                    "and si.icid in (select icid from ic_card where icisn=? ) limit 1",
                    new Object[] { ed.getSid(),EntranceICFinalData.SCHOOLICARD_STATE_ON,icisn}, new RowMapper<Long>() {
                        @Override
                        public Long mapRow(ResultSet rs, int arg1)
                            throws SQLException {
                            return rs.getLong("icid");
                        }
                    });
            if (null != scard_id && scard_id > 0) {
                System.out.println(sn + " is sn,icisn:"+icisn+",scard_id:"+scard_id);
            }else{
                System.out.println("card is not schools,"+sn + " is sn,icisn:"+icisn+",ed.getSid:"+ed.getSid());
                return new long[] { EntranceICFinalData.SWINGICCARD_STATE_IC_NOTHING };//打卡失败,非该校的启用卡 
            }
            
            //学校教师卡
            SchoolTeacherIcard si = (SchoolTeacherIcard) commonDao.listByObject(
                            "select * from school_teacher_icard where icid=?",
                            new Object[] { scard_id},new SchoolTeacherIcardRowMapper());
            if(null != si){//教师记录考勤
                // 教师打卡时间标准
                SchoolGradeAttendance sga = (SchoolGradeAttendance) commonDao
                        .listByObject(
                                "SELECT sga.* FROM school_grade_attendance sga where sga.gid=(select gid from school_teacher where tid=?) limit 1",
                                new Object[] { si.getTid() },
                                new SchoolGradeAttendanceRowMapper());
                TeacherIcardInfo tii = new TeacherIcardInfo();
                Timestamp cdate = new Timestamp(new Date().getTime());
                if (null != recordTime) {
                    try {  
                        cdate = Timestamp.valueOf(recordTime);  
                    } catch (Exception e) {  
                        e.printStackTrace();  
                    }
                }
                  
                tii.setCdate(cdate);
                tii.setType(operate);
                tii.setIcid(scard_id);
                tii.setTid(si.getTid());
                tii.setTimetype(getTimeTypebyCdate(cdate, operate, sga));
                
//                TeacherIcardInfo ret = (TeacherIcardInfo) commonDao.listByObject(
//                        "select * from teacher_icard_info where tid=? and icid=? and type=? and cdate=? having count(*) > 0", 
//                        new Object[]{si.getTid(),scard_id,operate,cdate},new TeacherIcardInfoRowMapper());
                TeacherIcardInfo ret = (TeacherIcardInfo) commonDao.listByObject(
                        "select * from teacher_icard_info where tid=? and icid=? and type=? and left(cdate,16)=? having count(*) > 0", 
                        new Object[]{si.getTid(),scard_id,operate,String.valueOf(cdate).substring(0, Constant.num_16)},
                        new TeacherIcardInfoRowMapper());
                
                // select * from teacher_icard_info where tid=? and icid=? and type=? and left(cdate,16)=? having count(*) > 0
                // String.valueOf(cdate).substring(0, 16)
                
                if (null == ret) {
                    KeyHolder kh = commonDao.insert(
                            TeacherIcardInfoRowMapper.getPreparedStatementCreator(tii),
                            new GeneratedKeyHolder());
                    if (null != kh) {
                        return new long[] {EntranceICFinalData.SWINGICCARD_STATE_TEACHER_SUCCESS,
                                tii.getTid(), kh.getKey().longValue() };
                    } else {
                        return new long[] { EntranceICFinalData.SWINGICCARD_STATE_WRITE_ERROR };
                    } 
                } else {
                    return new long[] {EntranceICFinalData.SWINGICCARD_STATE_TEACHER_SUCCESS,
                            tii.getTid(), ret.getTiid() };
                }
            }
            
            //学校学生卡
            Long baby_uid = (Long) commonDao.listByObject("select cs.uid from class_student cs left join school_student_icard ssi " +
                    "on cs.csid=ssi.csid where ssi.icid=?",
                            new Object[] { scard_id}, new RowMapper<Long>() {
                                @Override
                                public Long mapRow(ResultSet rs, int arg1)
                                    throws SQLException {
                                    return rs.getLong("uid");
                                }
                            });
            if (null != baby_uid && baby_uid > 0) {
                UserIcardInfo ui = new UserIcardInfo();
                Timestamp cdate = new Timestamp(new Date().getTime());
                if (null != recordTime) {
                    try {  
                        cdate = Timestamp.valueOf(recordTime);  
                    } catch (Exception e) {  
                        e.printStackTrace();  
                    }
                }
                  
                ui.setCdate(cdate);
                ui.setType(operate);
                ui.setIcid(scard_id);
                ui.setUid(baby_uid);
//                UserIcardInfo ret = (UserIcardInfo) commonDao.listByObject(
//                        "select * from user_icard_info where uid=? and icid=? and type=? and cdate=? having count(*) > 0", 
//                        new Object[]{baby_uid,scard_id,operate,cdate},new UserIcardInfoRowMapper());
                UserIcardInfo ret = (UserIcardInfo) commonDao.listByObject(
                        "select * from user_icard_info where uid=? and icid=? and type=? and left(cdate,16)=? having count(*) > 0", 
                        new Object[]{baby_uid,scard_id,operate,String.valueOf(cdate).substring(0, Constant.num_16)},new UserIcardInfoRowMapper());
                if (null == ret) {
                    KeyHolder kh = commonDao.insert(
                            UserIcardInfoRowMapper.getPreparedStatementCreator(ui),
                            new GeneratedKeyHolder());
                    
                    if (null != kh) {
                        return new long[] {EntranceICFinalData.SWINGICCARD_STATE_USER_SUCCESS,
                                ui.getUid(), kh.getKey().longValue() };
                    } else {
                        return new long[] { EntranceICFinalData.SWINGICCARD_STATE_WRITE_ERROR };
                    } 
                } else {
                    return new long[] {EntranceICFinalData.SWINGICCARD_STATE_USER_SUCCESS,
                            ui.getUid(), ret.getUeid() };
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return new long[] { EntranceICFinalData.SWINGICCARD_STATE_SCHOOL_SUCCESS };
        
    }

    @Override
    public String updateImg(Long id, Long uid, long usertype, short operate) {
        if (EntranceICFinalData.SWINGICCARD_STATE_USER_SUCCESS == usertype) {
            // 普通用户
            String filename = MD5Util.getMD5(String.valueOf(new Date().getTime())).substring(0, Constant.num_10) + 
                    RandomUtil.genRandomNum(Constant.num_8, RandomUtil.PWD_TYPE_NUM_AND_CHAR)+".jpg";
//            String filename = uid
//                    + "_"
//                    + id
//                    + "_"
//                    + RandomUtil.genRandomNum(Constant.num_8,
//                            RandomUtil.PWD_TYPE_NUM_AND_CHAR) + ".jpg";
            if (commonDao.update(
                    "update user_icard_info set img=? where ueid=?",
                    new Object[] { filename, id }) >= 1) {
                if (operate == IEntranceCardService.OPERATE_IN) {
                    return SystemConfigStatic.video_user_in_path + filename;
                } else if (operate == IEntranceCardService.OPERATE_OUT) {
                    return SystemConfigStatic.video_user_out_path + filename;
                } else {
                    return null;
                }
            } else {
                return null;
            }
        } else if (EntranceICFinalData.SWINGICCARD_STATE_TEACHER_SUCCESS == usertype) {
            // 教师考勤
            String filename = uid
                    + "_"
                    + id
                    + "_"
                    + RandomUtil.genRandomNum(Constant.num_8,
                            RandomUtil.PWD_TYPE_NUM_AND_CHAR) + ".jpg";
            if (commonDao.update(
                    "update teacher_icard_info set img=? where tiid=?",
                    new Object[] { filename, id }) >= 1) {
                if (operate == IEntranceCardService.OPERATE_IN) {
                    return SystemConfigStatic.video_teacher_in_path + filename;
                } else if (operate == IEntranceCardService.OPERATE_OUT) {
                    return SystemConfigStatic.video_teacher_out_path + filename;
                } else {
                    return null;
                }
            } else {
                return null;
            }
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<EntranceDevice> searchEntranceDeviceAll() {
        return (List<EntranceDevice>) commonDao.list(
                "select * from entrance_device", new EntranceDeviceRowMapper());
    }

    /**
     * 获取教师打卡的时间类型
     * 
     * @param cDate
     * @param operate
     * @param sadate
     * @param eadate
     * @param spdate
     * @param epdate
     * @return
     */
    public static short getTimeTypebyCdate(Timestamp cDate, short operate,
            SchoolGradeAttendance sga) {
        Time t_cDate = new Time(cDate.getTime());
        Time new_t_cDate = Time.valueOf(t_cDate.toString());// t_cDate为util.Date
        short timeType;
        // 1:<=上午结束的进入时间 ,2:>上午结束<=下午结束的进入时间,3:<=下午开始的退出时间
        // ,4:>下午开始的退出时间,5:>下午结束的进入时间或者无效的刷卡时间)
        if (null == sga) {
            timeType = IEntranceCardService.TIME_N_IN;
        } else {
            if (IEntranceCardService.OPERATE_IN == operate) {
                if (null == sga.getEadate()) { // 上午结束时间为空
                    timeType = IEntranceCardService.TIME_M_IN;
                } else {
                    if (new_t_cDate.getTime() <= sga.getEadate().getTime()) {
                        timeType = IEntranceCardService.TIME_M_IN;
                    } else if (new_t_cDate.getTime() <= sga.getEpdate()
                            .getTime()) {
                        timeType = IEntranceCardService.TIME_A_IN;
                    } else {
                        timeType = IEntranceCardService.TIME_N_IN;
                    }
                }
            } else if (IEntranceCardService.OPERATE_OUT == operate) {
                if (null == sga.getSpdate()) { // 下午开始时间为空
                    timeType = IEntranceCardService.TIME_A_OUT;
                } else {
                    if (new_t_cDate.getTime() <= sga.getSpdate().getTime()) {
                        timeType = IEntranceCardService.TIME_M_OUT;
                    } else {
                        timeType = IEntranceCardService.TIME_A_OUT;
                    }
                }
            } else {
                timeType = IEntranceCardService.TIME_N_IN;
            }
        }
        return timeType;
    }

    @Override
    public Map<String, Object> searchProxyEntrance(int page, int page_size,
            Long uid) {
        if (null == uid) {
            return null;
        }
        return commonDao
                .queryPage(
                        "select * from entrance_device as ed left join school as s on s.sid=ed.sid left join video_device as vd " +
                        "on vd.vid=ed.vdid left join proxy_user as pu on pu.pid=ed.pid left JOIN `user` as u on u.uid=pu.uid where u.uid=?",
                        page, page_size, new Object[] { uid },
                        new EntranceDeviceRowMapper(
                                EntranceDeviceRowMapper.AND_SCHOOL_AND_VIDEO));
    }

    @Override
    public int updateBindVideo(Long eid, Long vid, Long uid) {
        commonDao
        .update("update entrance_device as ed left join proxy_user as pu on pu.pid=ed.pid LEFT JOIN `user` as u on " +
                "u.uid=pu.uid LEFT JOIN video_device as vd on vd.pid=pu.pid set ed.vdid=? where u.uid=? and vd.vid=? and ed.eid=?",
                new Object[] { vid, uid, vid, eid });
        entranceInitCommonService.initEntrance();
        return 1;
    }

    @Override
    public int updateAssignEntrance(Long eid, Integer sid, Long uid) {
        commonDao
                .update("update entrance_device as ed left join proxy_user as pu on pu.pid=ed.pid left join school as s " +
                        "on s.pid=ed.pid left join `user` as u on u.uid=pu.uid set ed.sid=?,ed.poxystate=? where u.uid=? and eid=?",
                        new Object[] { sid, IAdminEntranceService.POXYSTATE_SCHOOL,uid, eid });
        entranceInitCommonService.initEntrance();
        return 1;
    }

    @Override
    public void updateVideoUrlIP(Long vid, String newIP){
        commonDao.update("update video_device set urlIP=? where vid=?", new Object[] {newIP,vid});
    }
    
    
    public void setEntranceInitCommonService(
            IEntranceInitCommonService entranceInitCommonService) {
        this.entranceInitCommonService = entranceInitCommonService;
    }

}
